
#include "flexHalcon.h"
#include <algorithm>
#include "HalconCpp.h"
#include "HTuple.h"
#include <map>
#include <mutex>
#include <string>
#include <QString>
#include "AppDataDef.h"
#include "mtp.h"

#ifndef __APPLE__
  #include <hdevengine/HDevEngineCpp.h>
#else
  #include <HDevEngineCpp/HDevEngineCpp.h>
#endif

using namespace HalconCpp;
using namespace HDevEngineCpp;


 flexHalcon::flexHalcon()
 {}

 flexHalcon::flexHalcon(QString fileFullPath):IHalcon(fileFullPath)
 { }

 flexHalcon::~flexHalcon()
 {}

 void flexHalcon::GetImgProResult(
	 IN HObject const& Image, IN HObject const& InRegion,
	 OUT HObject& ResultRegion, OUT HObject& CenterCross, OUT HObject& ResultXld, OUT HObject& ImageReduced,
	 OUT HObject& SearchContourXld, OUT HObject& PointCrossXld,
	 IN HTuple ModelID, IN HTuple MetrologyHandle, IN HTuple Mat, IN HTuple miniScore, IN HTuple ImgProcessType,
	 IN HTuple  StandOffsetX, IN HTuple StandOffsetY,
	 IN HTuple  StandImgPosX, IN HTuple StandImgPosY, IN HTuple StandImgPosAngle,
	 IN HTuple RotateCenterImgX, IN HTuple  RotateCenterImgY,
	 IN HTuple ManualBCX, IN HTuple ManualBCY, IN HTuple ManualBCR,
	 IN HTuple  TrayOffsetX, IN HTuple  TrayOffsetY, IN HTuple  TrayOffsetR, IN HTuple  orientation,
	 OUT HTuple* iResult, HTuple* findRow, HTuple* findColumn, HTuple* findAngle, HTuple* findScale, HTuple* findScore,
	 HTuple* OffsetX, HTuple* OffsetY, HTuple* OffsetR)
 {
	 try
	 {
		 HDevEngineCpp::HDevProcedure procedure(GetProgram(m_ResourcePath + m_HdevName), ToSTR(GetImgProResult));
		 HDevEngineCpp::HDevProcedureCall call(procedure);
		 ParamHandler<HObject>::SetParameter(call, ToSTR(Image), Image);
		 ParamHandler<HObject>::SetParameter(call, ToSTR(InRegion), InRegion);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(ModelID), ModelID);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(MetrologyHandle), MetrologyHandle);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(Mat), Mat);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(miniScore), miniScore);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(ImgProcessType), ImgProcessType);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(StandOffsetX), StandOffsetX);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(StandOffsetY), StandOffsetY);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(StandImgPosX), StandImgPosX);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(StandImgPosY), StandImgPosY);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(StandImgPosAngle), StandImgPosAngle);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(RotateCenterImgX), RotateCenterImgX);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(RotateCenterImgY), RotateCenterImgY);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(ManualBCX), ManualBCX);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(ManualBCY), ManualBCY);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(ManualBCR), ManualBCR);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(TrayOffsetX), TrayOffsetX);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(TrayOffsetY), TrayOffsetY);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(TrayOffsetR), TrayOffsetR); 
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(orientation), orientation);
		 call.Execute();

		 ResultRegion = ParamHandler<HObject>::GetParameter(call, ToSTR(ResultRegion));
		 CenterCross = ParamHandler<HObject>::GetParameter(call, ToSTR(CenterCross));
		 ResultXld = ParamHandler<HObject>::GetParameter(call, ToSTR(ResultXld));
		 ImageReduced = ParamHandler<HObject>::GetParameter(call, ToSTR(ImageReduced));
		 SearchContourXld = ParamHandler<HObject>::GetParameter(call, ToSTR(SearchContourXld));
		 PointCrossXld = ParamHandler<HObject>::GetParameter(call, ToSTR(PointCrossXld));

		 *iResult = ParamHandler<HTuple>::GetParameter(call, ToSTR(iResult));
		 *findRow = ParamHandler<HTuple>::GetParameter(call, ToSTR(findRow));
		 *findColumn = ParamHandler<HTuple>::GetParameter(call, ToSTR(findColumn));
		 *findAngle = ParamHandler<HTuple>::GetParameter(call, ToSTR(findAngle));
		 *findScale = ParamHandler<HTuple>::GetParameter(call, ToSTR(findScale));
		 *findScore = ParamHandler<HTuple>::GetParameter(call, ToSTR(findScore));

		 *OffsetX = ParamHandler<HTuple>::GetParameter(call, ToSTR(OffsetX));
		 *OffsetY = ParamHandler<HTuple>::GetParameter(call, ToSTR(OffsetY));
		 *OffsetR = ParamHandler<HTuple>::GetParameter(call, ToSTR(OffsetR));
     }
	 catch (HDevEngineException e)
	 {
		 std::string text = e.Message();
		 //log(text.data());
		 LOG_DEBUG(GetmtpLogger(), text);
	 }
 }


 void flexHalcon::RotateCenterMove(
	 IN HTuple ReMat,IN HTuple RobotPosX1, IN HTuple RobotPosY1, IN HTuple  RobotPosX2,IN HTuple RobotPosY2, 
	 IN HTuple RotateCenterImgX, IN HTuple  RotateCenterImgY,  OUT HTuple* MovedCenterImgX, HTuple* MovedCenterImgY)
 {
	 try
	 {
		 HDevEngineCpp::HDevProcedure procedure(GetProgram(m_ResourcePath + m_HdevName), ToSTR(RotateCenterMove));
		 HDevEngineCpp::HDevProcedureCall call(procedure);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(ReMat), ReMat);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(RotateCenterImgX), RotateCenterImgX);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(RotateCenterImgY), RotateCenterImgY);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(RobotPosX1), RobotPosX1);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(RobotPosY1), RobotPosY1);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(RobotPosX2), RobotPosX2);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(RobotPosY2), RobotPosY2);
		 call.Execute();
		 *MovedCenterImgX = ParamHandler<HTuple>::GetParameter(call, ToSTR(MovedCenterImgX));
		 *MovedCenterImgY = ParamHandler<HTuple>::GetParameter(call, ToSTR(MovedCenterImgY));

	 }
	 catch (HDevEngineException e)
	 {
		 std::string text = e.Message();
		 //log(text.data());
		 LOG_DEBUG(GetmtpLogger(), text);
	 }
 }


 void  flexHalcon::Get2DCode(IN HObject const& Image, HObject const& InRegion, OUT HObject& OutRegion, HObject& OutXld, IN HTuple& DataCodeHandle, HTuple iType, OUT HTuple* strCode, HTuple* iError)
 {
	 HDevEngineCpp::HDevProcedure procedure(GetProgram(m_ResourcePath + m_HdevName), ToSTR(Get2DCode));
	 HDevEngineCpp::HDevProcedureCall call(procedure);

	 ParamHandler<HObject>::SetParameter(call, ToSTR(Image), Image);
	 ParamHandler<HObject>::SetParameter(call, ToSTR(InRegion), InRegion);

	 ParamHandler<HTuple>::SetParameter(call, ToSTR(DataCodeHandle), DataCodeHandle);
	 ParamHandler<HTuple>::SetParameter(call, ToSTR(iType), iType);
	 call.Execute();

	 OutRegion = ParamHandler<HObject>::GetParameter(call, ToSTR(OutRegion));
	 OutXld = ParamHandler<HObject>::GetParameter(call, ToSTR(OutXld));
	 *strCode = ParamHandler<HTuple>::GetParameter(call, ToSTR(strCode));
	 *iError = ParamHandler<HTuple>::GetParameter(call, ToSTR(iError));
 }

 void flexHalcon::CropImage(IN HObject const& Image,
	   IN HObject& Roi1, IN HObject& Roi2, IN  HObject& Roi3,
	   OUT HObject& Image1, OUT HObject& Image2, OUT HObject& Image3, 
	   OUT HObject& CodeImage1, OUT HObject& CodeImage2, OUT HObject& CodeImage3,
	   IN HTuple ImgGroup)
 {
	 try
	 {
		 HDevEngineCpp::HDevProcedure procedure(GetProgram(m_ResourcePath + m_HdevName), ToSTR(CropImage));
		 HDevEngineCpp::HDevProcedureCall call(procedure);
		 ParamHandler<HObject>::SetParameter(call, ToSTR(Image), Image);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(ImgGroup), ImgGroup);

		 ParamHandler<HObject>::SetParameter(call, ToSTR(Roi1), Roi1);
		 ParamHandler<HObject>::SetParameter(call, ToSTR(Roi2), Roi2);
		 ParamHandler<HObject>::SetParameter(call, ToSTR(Roi3), Roi3);

		 call.Execute();

		 Image1 = ParamHandler<HObject>::GetParameter(call, ToSTR(Image1));
		 Image2 = ParamHandler<HObject>::GetParameter(call, ToSTR(Image2));
		 Image3 = ParamHandler<HObject>::GetParameter(call, ToSTR(Image3));

		 CodeImage1 = ParamHandler<HObject>::GetParameter(call, ToSTR(CodeImage1));
		 CodeImage2 = ParamHandler<HObject>::GetParameter(call, ToSTR(CodeImage2));
		 CodeImage3 = ParamHandler<HObject>::GetParameter(call, ToSTR(CodeImage3));

	/*	 Roi1 = ParamHandler<HObject>::GetParameter(call, ToSTR(Roi1));
		 Roi2 = ParamHandler<HObject>::GetParameter(call, ToSTR(Roi2));
		 Roi3 = ParamHandler<HObject>::GetParameter(call, ToSTR(Roi3));*/
	 }
	 catch (HDevEngineException e)
	 {
		 std::string text = e.Message();
		 //log(text.data());
		 LOG_DEBUG(GetmtpLogger(), text);
	 }
 }

 void flexHalcon::GetStdImgPoint(IN HObject const& Image, IN HObject const& Region,
	 OUT HObject& OutRegion, HObject& OutXld,
	 IN HTuple iType, IN HTuple HandleID, IN HTuple Mat, IN HTuple Para,
	 OUT HTuple* findRow, HTuple* findColumn, HTuple* findAngle, HTuple* iError)
 {
	 HDevEngineCpp::HDevProcedure procedure(GetProgram(m_ResourcePath + m_HdevName), ToSTR(GetStdImgPoint));
	 HDevEngineCpp::HDevProcedureCall call(procedure);
	 ParamHandler<HObject>::SetParameter(call, ToSTR(Image), Image);
	 ParamHandler<HObject>::SetParameter(call, ToSTR(Region), Region);

	 ParamHandler<HTuple>::SetParameter(call, ToSTR(iType), iType);
	 ParamHandler<HTuple>::SetParameter(call, ToSTR(HandleID), HandleID);
	 ParamHandler<HTuple>::SetParameter(call, ToSTR(Mat), Mat);
	 ParamHandler<HTuple>::SetParameter(call, ToSTR(Para), Para);

	 call.Execute();

	 OutRegion = ParamHandler<HObject>::GetParameter(call, ToSTR(OutRegion));
	 OutXld = ParamHandler<HObject>::GetParameter(call, ToSTR(OutXld));

	 *findRow = ParamHandler<HTuple>::GetParameter(call, ToSTR(findRow));
	 *findColumn = ParamHandler<HTuple>::GetParameter(call, ToSTR(findColumn));
	 *findAngle = ParamHandler<HTuple>::GetParameter(call, ToSTR(findAngle));
	 *iError = ParamHandler<HTuple>::GetParameter(call, ToSTR(iError));
 }

 void flexHalcon::ProcessMetrologyResult(IN HTuple MetrologyHandle, OUT HTuple* findRow, HTuple* findColumn, HTuple* findAngle, HTuple* iResult)
 {
	 try
	 {
		 HDevEngineCpp::HDevProcedure procedure(GetProgram(m_ResourcePath + m_HdevName), ToSTR(ProcessMetrologyResult));
		 HDevEngineCpp::HDevProcedureCall call(procedure);
		 ParamHandler<HTuple>::SetParameter(call, ToSTR(MetrologyHandle), MetrologyHandle);
		 call.Execute();
		 *findRow = ParamHandler<HTuple>::GetParameter(call, ToSTR(findRow));
		 *findColumn = ParamHandler<HTuple>::GetParameter(call, ToSTR(findColumn));
		 *findAngle = ParamHandler<HTuple>::GetParameter(call, ToSTR(findAngle));
		 *iResult = ParamHandler<HTuple>::GetParameter(call, ToSTR(iResult));
	 }
	 catch (HDevEngineException e)
	 {
		 std::string text = e.Message();
		 //log(text.data());
		 LOG_DEBUG(GetmtpLogger(), text);
	 }
 }

 //ParamHandler<HObject>::SetParameter(call, ToSTR(),);
 //ParamHandler<HTuple>::SetParameter(call, ToSTR(), );
 //= ParamHandler<HObject>::GetParameter(call, ToSTR());
 //= ParamHandler<HTuple>::GetParameter(call, ToSTR());